home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Talks & Papers / Timothy Knox / yerk 3.66 / System source / Files < prev    next >
Text File  |  1994-06-24  |  15KB  |  504 lines

  1. \ Files  - file object and loader
  2. \ 09/10/84  CBD Version 1.0
  3. \ 10/12/84  CBD Added loader,  Length: -> bytesRead:
  4. \ 12/14/84  cbd nested loads, no default:
  5. \  7/04/86  cdn Added HFS references
  6. \  7/13/86  cdn Moved in SFPReply
  7. \  8/15/86  rfd Skip HFS search is vRefNum supplied
  8. \  8/26/86  cdn Added classinit for File
  9. \  9/8/86   rfd added dirfind resfind etc. to speed up open
  10. \ 12/3/87    rfl fixed pileup of pathnames in hopen
  11. \ 12/3/87   rfl addef flushvol:
  12. \  9/5/88    rfl    fixed hfs?
  13. \ 12/14/88    rfl fixing data record for hfs
  14. \  5/23/90    rfl added event processing during file loading
  15. \  7/25/90    rfl fixed load so that ?pause works during +echo
  16. \  9/27/90    rfl    savesig now finds app signature
  17. \ 11/12/90    rfl recoded volname?
  18. \ 12/14/90    rfl added font change to //
  19. \ 12/29/90    rfl    mods for path now sarray object
  20. \  1/31/91    rfl    fixed saveSig to get signature, not file name; font stuff now
  21. \                here; no longer need chicago 9.
  22. \  1/26/92    rfl    fixed Savesig to use heap file object. remove: loadfile closed the file.
  23. \                This wasn't good if the file was the standalone application.
  24. \ 11/25/92    rfl    Changed Last: to look at file size instead of using $ ffffff.
  25. \ 12/11/92    rfl    pulled ftype out of file, now global; added put: for single character write
  26. \                removed antiquated words like sony, external, profile; added where:
  27. \  4/30/93    rfl    Now when saving a snapshot of the environment, you no longer
  28. \                have to worry about closing the windows. The open windows are first marked
  29. \                closed, the file is saved, then they are all marked open again
  30. \  5/10/93    rfl    shortened filinit
  31. \  5/12/93    rfl    Hopen: and orf now lock down strings because of occasional problems
  32. \                 not building search path correctly due to moving of data
  33. \  5/17/93    rfl    removed res string call from clear: filelist so yerk.rsrc not
  34. \               necessary for string
  35. \  6/04/93    rfl    modified for source documentation; sfind and screate moved from 'mod'
  36. \  6/17/93    rfl    srcCreate now replaces a filemark with no yerk words defined after it.
  37. \  1/01/94    rfl incorporated file related words from base and put into class file as methods
  38.  
  39. Decimal
  40.  
  41. \ ( n fcb(abs) -- )
  42. Create dirfind
  43.     popA0
  44.     popD0
  45.     $ A260 w,
  46.     pushD0
  47.     next,
  48.  
  49. : volname? { strobj -- b }
  50.     start: strobj next: strobj
  51.     IF ascii : <> ELSE false THEN ;
  52.  
  53. 0 -> quitvec    \ leave vectors in a clean state
  54. 0 -> abortvec
  55.  
  56. : (nevent1) decho IF ?pause THEN ;
  57. 'c (nevent1) vect nEvent        \ use as stub until Event is loaded
  58.  
  59. : -echo  false -> decho ;
  60. : +echo  true  -> decho ;
  61. : -curs  false -> curs  ;
  62. : +curs  true  -> curs  ;
  63.  
  64. \ ( -- T or F ) returns true if on HFS
  65. : hfs? $ 3f6 -base w@ 0> ;
  66.  
  67. 0 value path    \ is instantiated by getPtxt
  68.  
  69. \  Strip volume name & HFS paths from a file name
  70. : MFSname { addr len -- addr' len' }
  71.     len ++> addr
  72.     len 0
  73.     DO    -1 ++> addr                \ scan through string backwards
  74.         addr c@ ascii : =        \ first colon we see, we stop
  75.         IF 1 ++> addr i -> len leave THEN
  76.     LOOP
  77.     addr len
  78. ;
  79.  
  80. : UpCase true -> ucase ;
  81. : LoCase false ->  ucase ;
  82.  
  83. \ ( addr len -- pfa len t OR f )  find word for name on stack. map to uppercase
  84. \   by default, but if ucase is false, then leave text alone.
  85. : sfind here >str255 ucase
  86.     IF 1+ here c@ >uc here ELSE -base THEN latest (find) ;
  87.  
  88. \ ( addr len -- )  create a new dict name/link for name on stack
  89. : sCreate docs IF line# w, THEN        \ for source documentation
  90.     sfind IF here count type type# 184 ( is redefined ) cr 2drop THEN
  91.     createHdr -4 allot ;
  92.  
  93. \ don't allow two adjacent words to be file marks...this will
  94. \ prevent a load file from being embedded in the dictionary...unless the
  95. \ loadfile begins by defining yerk words...thus a loadfile cannot do any
  96. \ defining for this to work all the time.
  97. : srcCreate ( addr len -- )            \ create a filemark entry to dictionary
  98.     docs
  99.     IF dup 31 > ?error 187
  100.         latest name> @ fileMk =        \ is the last word a filemark?
  101.         IF latest dup >line -> dp pfa lfa @ current ! THEN    \ yes, so get rid of it
  102.         LoCase
  103.         screate
  104.         fileMk , 
  105.         UpCase
  106.     ELSE 2drop
  107.     THEN ;
  108.  
  109.     4 Ordered-Col    fTypes        \ list of filetypes used by all files for stdget:
  110.  
  111. :CLASS File  <Super Object
  112.  
  113.     134 Bytes        FCB            \ max MAC parameter block(108 but for hgetvinfo)
  114.     \ Standard File data
  115.     Int                Good        \ this is like a variable record
  116.     Var                fType
  117.     Int                vRefNum
  118.     Int                Version
  119.     64 Bytes        Filename    \ max size is 64
  120.  
  121.  
  122.     \ ( --)  Set the NamePtr field to the abs address of the file name field
  123.     :M  SETNAMEPTR: (abs) 144 + ^base 18 + ! ;M
  124.  
  125.     :M  CLEAR:        \ Erase a parm block
  126.         ^base  144 erase  ^base 144 + 64 blanks setNamePtr: self  ;M
  127.  
  128.     :M  CLOSE:  ^base (close)  ;M
  129.  
  130.     \ ( addr len -- )  assigns file name to fcb
  131.     :M  NAME:  clear: self ^base swap 64 min swap 144 + >str255 drop ;M
  132.  
  133.     \ ( dirid -- )  set the DirID for the fcb
  134.     :M  SETDIRID: ^base 48 + !  ;M
  135.  
  136.     \ ( -- dirid )  get the DirID for the fcb
  137.     :M  GETDIRID: ^base 48 + @  ;M
  138.  
  139.     \ ( vref# -- )  set the volRefNum for the fcb
  140.     :M  SETVREF:  ^base 22 + w! ;M
  141.  
  142.     \ ( -- vref# )  get the volRefNum for the fcb
  143.     :M  GETVREF:  ^base 22 + w@ ;M
  144.  
  145.     \ ( mode -- fCode )
  146.     :M  HOPEN: { mode \ fnam1 pathname rc -- }
  147.         path IF lock: path THEN
  148.         heap> String -> fnam1  new: fnam1
  149.         heap> String -> pathName new: pathName
  150.         addr: filename count put: fnam1
  151.         lock: fnam1
  152.         start: fnam1 path
  153.         IF  ascii : charOf: fnam1
  154.             IF drop ^base mode (open)    \ assumed to be qualified path name
  155.             ELSE
  156.                 limit: path 0
  157.                 DO i at: path put: pathname
  158.                     pathname volname? 0=  hfs? land
  159.                     IF    lock: pathname                                \ if not volume
  160.                         get: pathname name: self unlock: pathname    \ get dirid
  161.                         9 ^base +base dirfind drop
  162.                         getdirid: self
  163.                         get: fnam1 name: self
  164.                         setdirid: self
  165.                         ^base mode (open) -> rc    \ attempt to open
  166.                         rc 0= IF leave THEN        \ found it !!
  167.                     ELSE 
  168.                         pathName concat: fnam1
  169.                         lock: pathname get: pathname name: self unlock: pathname
  170.                         ^base mode  (open)  -> rc
  171.                         rc 0= IF leave THEN        \ found it !!
  172.                     THEN
  173.                 LOOP
  174.                 rc IF get: fnam1 name: self THEN
  175.                 rc    \ leave return code
  176.             THEN
  177.         ELSE
  178.             hfs? 0=        \ strip HFS paths under MFS
  179.             IF    ascii : charOf: fnam1
  180.                 IF    >R 0 -base                            \ setup for replace:
  181.                     get: fnam1 MFSname drop ptr: fnam1 R + -
  182.                     " :" drop R> 0> replace: fnam1        \ delete any path spec
  183.                     get: fnam1 addr: filename >str255 drop
  184.                 THEN
  185.             THEN
  186.             ^base mode (open)
  187.         THEN
  188.         release: fnam1 dispose> fnam1
  189.         release: pathname dispose> pathname
  190.         path IF unlock: path THEN
  191.     ;M
  192.  
  193.     \ ( -- fcode )  basic I/O operations
  194.     :M  OPEN:
  195.         ^base 22 + w@ ^base 48 + @ or
  196.         IF ^base 0 (open)
  197.         ELSE 0 Hopen: self THEN
  198.     ;M
  199.  
  200.     :M  NEW:    ^base  (make)  ;M
  201.     :M  DELETE: ^base (delete) ;M
  202.  
  203.     \ ( byteoffset -- fcode )  position relative to beginning-of-file
  204.     :M  MOVETO: ^base 1 rot (lseek)   ;M
  205.  
  206.     \ ( -- byteoffset ) current position relative to beginning-of-file
  207.     :M  WHERE: ^base 46 + @ ;M
  208.  
  209.     \ ( pos -- fcode )  set End-of-File to absolute byte position
  210.     :M  SETEOF: ^base 28 + !  ^base $ a012 (fdos) ;M
  211.  
  212.     \ ( -- fcode )  open and reset file or create new if not present
  213.     :M  CREATE: { \ volid -- fcode }
  214.         ^base 22 + w@ -> volid
  215.         open: self
  216.         -dup
  217.         IF    dup -43 =
  218.             volid ^base 22 + w!
  219.             IF    drop
  220.                 new: self -dup
  221.                 0= IF ^base 0 (open) THEN
  222.             THEN
  223.         ELSE
  224.             0 setEOF: self
  225.         THEN
  226.     ;M
  227.  
  228.     \ ( -- #bytes )  return logical eof for file currently open
  229.     :M  SIZE:  ^base $ a011 (fdos)  drop ^base 28 + @ ;M
  230.  
  231.     \ ( -- )  position to file's eof
  232.     :M  LAST:  size: self moveTo: self drop  ;M
  233.  
  234.     \ ( -- lengthRead )  return actual bytes read
  235.     :M  BYTESREAD:  ^base 40 + @ ;M
  236.  
  237.     \ ( -- fcbAddr )
  238.     :M  FCB:  ^base  ;M
  239.  
  240.     \ ( -- fcode )
  241.     :M  RESULT:  addr: fcb  16 + W@ ;M
  242.  
  243.     \ ( posMode -- )  Set position mode
  244.     :M  MODE:  ^base 44 + W!   ;M
  245.  
  246.     \ ( addr length -- fcode )
  247.     :M  READ: 0 mode: Self ^base swap rot (read)  ;M
  248.  
  249.     \ ( addr maxLen -- fcode )  Read terminating with CR
  250.     :M  READLINE:  $ 0d80 Mode: self ^base swap rot (read)  ;M
  251.  
  252.     \ ( addr length -- fcode )
  253.     :M  WRITE:  ^base  swap rot (write)  ;M
  254.  
  255.     \ ( n -- fcode )
  256.     :M  PUT: pad c! pad 1 write: self ;M
  257.  
  258.     \ ( -- )  Get name from input stream, and assign to fcb
  259.     :M  SETNAME:  word" count Name: self ;M
  260.  
  261.     \ ( -- addr len )  return filename
  262.     :M  GETNAME:  addr: fileName count   ;M
  263.  
  264.     \ ( -- )  print the filename
  265.     :M  PRINT:  getName: self  type    ;M
  266.  
  267.     \ ( drive# -- )  set default drive to drive#
  268.     :M  DRIVE:   Clear: self  setVRef: self  ^base $ a015 (fdos)
  269.         ?error 165   ;M    \ Drive change unsuccessful
  270.  
  271.     \ ( addr len -- eof )  Simulate a Yerk expect from disk
  272.     :M  EXPECT: { addr len -- }
  273.         addr len 1+ erase  addr len ReadLine: self  0=
  274.         IF  dEcho
  275.             IF  addr bytesRead: self  1+ type cr
  276.             THEN
  277.             addr bytesread: self + 1-  0 swap c!  0
  278.         ELSE  1 THEN   ;M
  279.  
  280.     \ ( -- eof )  Expect a line to the TIB
  281.     :M  QUERY:  0 -> in  Tib 128 Expect: self 1 ++> line# ;M
  282.  
  283.     \ interpret the file as a Yerk source file
  284.     \ ( -- )  name must first be set
  285.     :M  INTERPRET: { \ icurs -- } -1 -> line#
  286.         open: self  classErr" 132
  287.         getName: self
  288.         srcCreate            \ create file mark entry
  289.         curs -> icurs -curs    \ Preserve cursor status
  290.         BEGIN   nEvent
  291.                 query: self   0=
  292.         WHILE  Interpret State   0= dEcho   And
  293.             IF  ok  THEN
  294.         REPEAT  ?exec close: self drop
  295.         icurs -> curs -1 -> line#  ;M    \ Restore cursor status
  296.  
  297.      :M  FLUSHVOL: ^base $ A013 (fdos) drop ;M
  298.  
  299.     \ ( taddr tlen -- fcode )
  300.     :M  RENAME: { taddr tlen -- result }
  301.         taddr tlen str255
  302.         ^base 28 + !  ^base $ A00B (fdos) ;M
  303.  
  304.     \ ( -- fcode )
  305.     :M  OPENREADONLY:
  306.         ^base 22 + w@ ^base 48 + @ or
  307.         IF ^base 1 (open)
  308.         ELSE 1 Hopen: self THEN ;M
  309.  
  310.     \ ( -- type )
  311.     :M  GETTYPE:  ^base 32 + @ ;M
  312.  
  313.     \ ( -- fcode )  fills the parameter block with file info
  314.     :M  GETFILEINFO:  ^base $ A20C (fdos)  ;M
  315.  
  316.     \ ( -- fcode )
  317.     :M  SETFILEINFO:  ^base $ A00D (fdos)  ;M    \ immed doesn't work for some reason
  318.  
  319.     \ ( ftype sig -- )  Set file type, signature
  320.     :M  SET: { ftyp sig -- }        \ Sets file type, signature - recoded file-install
  321.         getDirID: self                \ Save DirID
  322.         0 setDirID: self            \ and clear it (otherwise we'll get
  323.         getFileInfo: self  drop        \  "file not found")
  324.         sig  ^base  $ 24 +  !        \ Set signature
  325.         ftyp ^base  $ 20 +  !        \ Set type
  326.         0 setDirID: self
  327.         setFileInfo: self  drop
  328.         setDirID: self                 \ Restore DirID
  329.         flushVol: self ;M
  330.  
  331.     \ ( routine# -- bool )  call a Standard File Package routine
  332.     :M  SFPCALL:  makeInt $ a9ea Trap
  333.         get: good
  334.         IF get: vRefNum ^base 80 erase setNamePtr: self
  335.             setVref: self  True
  336.         ELSE  False
  337.         THEN     ;M
  338.  
  339.     \ ( type0 ...typeN #types -- bool )  call SFGetFile
  340.     :M  STDGET:  clear: fTypes  dup 0>
  341.         IF 0 DO add: fTypes LOOP
  342.         ELSE drop THEN
  343.         $ 640064 0 0  size: fTypes -dup 0= IF -1 THEN makeInt
  344.         ixAddr: fTypes +base 0 abs: good
  345.         2 sfpCall: self  ;M
  346.  
  347.     \ call SFPutFile - takes promp, origName strings
  348.     :M  STDPUT:  { pAddr pLen nAddr nLen -- bool }
  349.         pLen pad c! pAddr pad 1+ pLen cmove
  350.         $ 640064  pad +base  nAddr nLen str255 0 abs: good
  351.         1 sfpCall: self  ;M
  352.  
  353.     :M  CLASSINIT:  clear: self  ;M
  354.  
  355. ;CLASS
  356.  
  357. ' File 'c fFcb !        \ set ffcb to member of file class
  358.  
  359. \ FileList keeps a stack of open load files for nested loads.
  360. :CLASS FileList  <Super Ordered-Col
  361.  
  362.     \ release heap for the top element
  363.     :M  REMOVE:  get: size dup 0= classerr" 137
  364.         1- ^elem close: [ dup @ ] drop
  365.         dispose  -1 +: size  ;M
  366.  
  367.     \ ( -- ^file ) add a new file to the stack
  368.     :M  NEW:  heap> file  add: super   ;M
  369.  
  370.     \ interpret the top file
  371.     :M  INTERPRET:  interpret: [ last: self ]  ;M
  372.  
  373.     \ ( -- )  remove all currently open files
  374.     :M  CLEAR:  ." File stack: " cr \ type# 180 ( File stack: ) cr
  375.         get: size 0
  376.         DO print: [ last: self ] cr remove: self
  377.         LOOP  ;M
  378.  
  379.     \ ( -- )  initialize list at startup
  380.     :M  INIT:   clear: super  ;M
  381.  
  382. ;CLASS
  383.  
  384. 6 fileList loadFile
  385.  
  386. : lastLoad  last: loadFile ;
  387. 'c lastLoad vect topFile
  388.  
  389. \ ( addr len -- )  open named resource file
  390. : orf { \ fnam1 pathname RC nfcb -- }
  391.     new: loadFile name: topFile
  392.     word0 getname: topfile str255 $ a997 trap i->l -1
  393.      = IF
  394.        HFS?  path land IF
  395.         HEAP> String -> fnam1 new: fnam1
  396.         heap> string -> pathName new: pathName
  397.         getname: topfile put: fnam1 lock: fnam1
  398.         -1 -> RC
  399.         HEAP> file -> nfcb
  400.         limit: path 0 DO
  401.             i at: path put: pathname
  402.             start: fnam1 get: fnam1 add: pathname
  403.             lock: pathname get: pathname
  404.             name: nfcb 9 nfcb +base dirfind
  405.             0= IF nfcb 30 + c@ 16 and ELSE true Then  not
  406.             IF
  407.                 word0 get: pathname STR255
  408.                 $ a997 trap i->l -> RC
  409.                 LEAVE
  410.             THEN unlock: pathname
  411.         LOOP
  412.         Dispose> nfcb
  413.         release: pathname dispose> pathname
  414.         release: fnam1 dispose> fnam1
  415.     ELSE   word0 getname: topfile STR255 $ a997 trap i->l -> rc
  416.     THEN     RC -1 = abort" resource file open failed"
  417.   THEN   remove: loadfile
  418. ;
  419. \ ( addr len - )
  420. :F OpenResFile ORF ;F
  421.  
  422. \ used to be defined in Event
  423. \ ( val -- )  set text characteristics for current grafPort
  424. : tfont  makeint $ a887 trap ;
  425. : tFace  makeInt $ a888 trap ;
  426. : tMode  makeInt $ a889 trap ;
  427. : tSize  makeInt $ a88a trap ;
  428.  
  429. \ nesting loader. Use: // filename
  430. : // { \ lcurs -- }
  431.     curs -> lcurs -curs    \ Preserve cursor status
  432.     new: loadFile  setName: topFile
  433.     getName: topFile  3 tfont 1 tface type# 173 ( Loading: ) type 0 tface 4 tfont cr
  434.     interpret: topFile  remove: loadFile
  435.     lcurs -> curs ;        \ Restore cursor status
  436.  
  437. \ ================ Save ====================
  438.  
  439. 'type COM  CONSTANT saveType            \ file type = 'COM '
  440. \ use current application signature
  441. : saveSig { \ myFile -- }
  442.     heap> file -> myFile                \ need a file structure
  443.     $ 910 -base count name: myFile        \ get nucleus name
  444.     getFileInfo: myFile drop            \ get info
  445.     myFile 36 + @ dispose> myFile ;        \ get signature
  446.  
  447. ( -- Length of dictionary to be saved )
  448. : flen      here Begin-dp @  - ;
  449.  
  450. Forward purge    \ defined in Ovl
  451.  
  452. 0 Variable  H1 here 16 allot 16 erase
  453.  
  454. \ mark all windows closed
  455. : togWindows { flag \ theWindow -- } 0 $ a924 trap
  456.     BEGIN -base -> theWindow
  457.           theWindow $ 90 + @                \ get next window in list
  458.            flag theWindow 184 + w! ( markClosed: theWindow ) dup 0=    \ continue until no more windows
  459.     UNTIL drop ;
  460. : markWindowsClosed 0 togWindows ;
  461. : markWindowsOpen   1 togWindows ;
  462.  
  463. \ Reuse target BIN file- so as not to wrestle file from it's folde
  464. \ ( -- )  Save the user dictionary
  465. : (Save) markWindowsClosed
  466.     purge
  467.     path 0 -> path    \ temporarily zero out path
  468.     setNamePtr: ffcb
  469.     create: fFcb ?error 107
  470.     \ SAVE-HEAD
  471.         here H1 !            \ Save DP
  472.         fence H1 4+ !        \ Save FENCE
  473.         voc-link H1 8+ !    \ Save VOC-LINK
  474.         latest H1 12 + !    \ Save latest NFA
  475.         0 mode: fFcb  0 fFcb 46 + w!
  476.         H1 16 write: fFcb ?error 101
  477.     \ WRITE-DICT
  478.         $ 10 fFcb $ 2E + W!
  479.         begin-dp @ flen write: fFcb ?error 105
  480.     saveType saveSig set: fFcb
  481.     close: fFcb drop
  482.     -> path            \ restore path
  483.     markWindowsOpen ;
  484.  
  485. \ Save command takes name from input stream
  486. : Save
  487.     setName: fFcb (save) ;
  488.  
  489. \ when // executes, it adds a new file object on the heap to a
  490. \ stack of files. This permits embedded loads, providing hierarchical
  491. \ nesting of source files.
  492.  
  493. : cleanUp  [Compile] ;class  clear: loadFile  init8  parmlist -1 -> line# ;
  494. : filinit   ' File 'c fFcb !  init: loadFile ;
  495.  
  496. 'c filinit -> objinit
  497. 'c cleanUp -> abortvec
  498.  
  499. 'type TEXT constant txType
  500.  
  501. \ true -> docs
  502.  
  503. // tool.load
  504.